package com.gitee.lichoking.mysoap.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 反射工具
 *
 * @Author lich
 * @Date 2021/6/1
 **/
public class ReflectionUtils {
    private static final String SET_PREFIX = "set";
    private static final String GET_PREFIX = "get";
    private static final String GET_CLASS = "getClass";

    public static <E> void set(Object classObj, Field field, E fieldObj) {
        String fieldName = field.getName();
        String setMethodName = new StringBuilder(SET_PREFIX).append(fieldName.substring(0, 1).toUpperCase())
                .append(fieldName.substring(1)).toString();
        Class fieldClass = field.getType();
        Method objMethod = null;
        try {
            objMethod = classObj.getClass().getMethod(setMethodName, fieldClass);
        } catch (NoSuchMethodException e) {
            throw new ReflectionException("方法名" + setMethodName + "不存在");
        }
        try {
            objMethod.invoke(classObj, fieldObj);
        } catch (IllegalAccessException illegalAccessException) {
            throw new ReflectionException("执行方法名" + setMethodName + "出错");
        } catch (InvocationTargetException invocationTargetException) {
            throw new ReflectionException("执行方法名" + setMethodName + "出错");
        }
    }

    public static <E> E get(Object classObj, Field field) {
        String fieldName = field.getName();
        String getMethodName = new StringBuilder(GET_PREFIX).append(fieldName.substring(0, 1).toUpperCase())
                .append(fieldName.substring(1)).toString();
        Class fieldClass = field.getType();
        Method objMethod = null;
        try {
            objMethod = classObj.getClass().getMethod(getMethodName, fieldClass);
        } catch (NoSuchMethodException e) {
            throw new ReflectionException("方法名" + getMethodName + "不存在");
        }
        try {
            return (E) objMethod.invoke(classObj);
        } catch (IllegalAccessException e) {
            throw new ReflectionException("执行方法名" + getMethodName + "出错");
        } catch (InvocationTargetException e) {
            throw new ReflectionException("执行方法名" + getMethodName + "出错");
        }
    }

    /**
     * 通过get方法获取fieldMap
     *
     * @param type
     * @return
     */
    public static Map<String, Method> getAllFiledByGetter(Class type) {
        Map<String, Method> fieldGetters = new HashMap<>(32);
        Method[] methods = type.getMethods();
        for (Method method : methods) {
            String methodName = method.getName();
            //跳过getClass方法
            if (GET_CLASS.equals(methodName)) {
                continue;
            }
            boolean getMethodFlag = methodName.startsWith(GET_PREFIX);
            //包好get并且下个字符是大写
            if (getMethodFlag && Character.isUpperCase(methodName.charAt(GET_PREFIX.length()))) {
                String fieldName = methodName.substring(GET_PREFIX.length());
                fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1);
                if (fieldGetters.get(fieldName) == null) {
                    fieldGetters.put(fieldName, method);
                } else {
                    throw new ReflectionException(fieldName + "有多个get方法");
                }
            }
        }
        return fieldGetters;
    }
}
